EDA: SiMWiSense: Simultaneous Multi-Subject Activity Classification Through Wi-Fi Signals¶
Equipe: Nobuko e Diogo
Novidades em Maio/2025
- Nomes das atividades no SiMWisense e Beamsense.
- Entendendo melhor os dados do conjunto Coarse
- Valores min, max por subportadora
- Bias do dataset
- Plotando TSNE do dataset
Abril/2025 Resumo do notebook
- Introdução
- Arquivos PCAP (dado bruto)
- Extração do CSI dos PCAP
- Divisão das matrizes em slots e batches
- Criando CSVs
- Exemplos das amostras
1. Introdução¶
Em contraste com a maioria dos datasets de Wi-Fi sensing que se concentram na classificação de atividades de um único indivÃduo por vez, este dataset foi desenvolvido a partir de uma de coleta com três indivÃduos executando simultaneamente 20 atividades diferentes. A coleta foi realizada com o uso de múltiplos monitores de CSI, em 3 2 ambientes distintos: (Sala de aula, escritório e cozinha).
A base da coleta é o uso do Channel State Information (CSI) — uma métrica da camada fÃsica do Wi-Fi, utilizada em estimativas e equalizações de canal. O CSI é altamente sensÃvel a alterações no ambiente fÃsico, sendo capaz de capturar variações provocadas por qualquer entidade presente entre o transmissor e o receptor.
Resumo das caracterÃsticas do dataset:
- Número de indivÃduos: 3.
- Tipo de atividades: 20 atividades distintas realizadas simultaneamente.
- Ambientes:
32 (Sala de aula, escritório ecozinha) - Dispositivos utilizados: 3 monitores de CSI e 1 Access Point (AP)
Hardware utilizado:
- 1 Netgear Nighthawk X4S AC2600 (Access Point) IEEE 802.11ac Wifi5
- 3 Asus RT-AC86U (monitores) IEEE 802.11ac Wifi5 com firmware alterado para captura
- Firmware para captura: Nexmon (também disponÃvel no Raspiberry Pi B3+/B4)
Cenário dos experimentos
+--------------------------------------------------+
| [M1] [M2] [M3] |
| |
| /--------\ /--------\ /--------\ |
| | Zona 1 | | Zona 2 | | Zona 3 | |
| \--------/ \--------/ \--------/ |
| |
| |
| |
| |
| (AP) |
| 🔵 |
+--------------------------------------------------+
Tipos de teste No README do repositório, os testes são descritos da seguinte forma:
| Teste | Descrição |
|---|---|
| Proximity Test | Resolve o problema da classificação simultânea de múltiplos sujeitos, utilizando o CSI do dispositivo mais próximo. Experimentalmente, é comprovado que a melhor acurácia é obtida com o transceptor mais próximo do sujeito. |
| Coarse Detection | Propõe uma detecção descentralizada para múltiplos sujeitos, atribuindo um modelo de aprendizado a cada dispositivo para identificar o sujeito mais próximo. Refere-se à identificação do sujeito (subject identification). |
| Fine-Grained Detection | Após a identificação do sujeito, um segundo modelo de deep learning é usado para classificar as atividades de forma mais precisa. |
O que não tem:
- O dataset não tem os dados do ambiente da cozinha.
- Os vÃdeos capturados para gerar o ground truth também não estão no dataset.
Descrição das 20 atividades (no SiWiSense):
- push forward,
- rotate,
- hands up and down,
- waive,
- brush,
- clap,
- sit,
- eat,
- drink,
- kick,
- bend forward,
- wash hands,
- call,
- browsing phone,
- check wrist,
- read,
- waive while sitting,
- writing,
- side bend,
- standing
Descrição das 20 atividades (no Beamsense):
- jogging
- clapping
- push forward,
- boxing,
- writing,
- brushing teeth,
- rotating,
- standing,
- eating,
- reading a book,
- waiving,
- walking,
- browsing phone,
- drinking, hands-up-down,
- phone call,
- side bend,
- check the wrist (watch),
- washing hands,
- browsing laptop.
2. Arquivos PCAP (dado bruto)¶
O repositório disponibiliza um arquivo .zip com aproximadamente 191 GB de dados. Esse arquivo é composto principalmente por múltiplos arquivos PCAP, contendo capturas de tráfego de rede. Além dos PCAPs, o .zip inclui diversos arquivos placeholder. O download completo levou cerca de 2 horas.
Focando nas pastas com PCAPs temos o seguninte:
Data
├── [proximity, coarse, fine_grained] → São os 3 testes.
├──── [Classroom, Office] → O lugar onde foi realizada a coleta.
├────── 80MHz/3mo → largura de banda e quantidade de monitores.
├──────── [m1, m2, m3] → medicões de cada monitor.
├────────── CSI_pcap → onde estão os arquivos .pcap.
├────────────[A,B,C,...].pcap → o nome do arquivo já indica a atividade.
!find ../Data -type d -name CSI_pcap | while read dir; do count=$(find "$dir" -maxdepth 1 -name '*.pcap' | wc -l); total_bytes=$(find "$dir" -maxdepth 1 -name '*.pcap' -exec du -bc {} + | grep total$ | awk '{print $1}'); if [ "$count" -gt 0 ]; then avg_bytes=$((total_bytes / count)); avg_human=$(numfmt --to=iec --suffix=B "$avg_bytes"); total_human=$(numfmt --to=iec --suffix=B "$total_bytes"); else avg_human="N/A"; total_human="0B"; fi; BLUE='\033[1;34m'; GREEN='\033[1;32m'; YELLOW='\033[1;33m'; MAGENTA='\033[1;35m'; NC='\033[0m' ; echo -e "${BLUE}$dir${NC} -> ${GREEN}$count arquivos${NC}, ${YELLOW}Total: $total_human${NC}, ${MAGENTA}Média: $avg_human${NC}"; done
../Data/coarse/Classroom/80MHz/3mo/m2/CSI_pcap -> 4 arquivos, Total: 1,7GB, Média: 421MB ../Data/coarse/Classroom/80MHz/3mo/m3/CSI_pcap -> 4 arquivos, Total: 1,7GB, Média: 423MB ../Data/coarse/Classroom/80MHz/3mo/m1/CSI_pcap -> 4 arquivos, Total: 1,7GB, Média: 420MB ../Data/coarse/Office/80MHz/3mo/m2/CSI_pcap -> 4 arquivos, Total: 1,8GB, Média: 458MB ../Data/coarse/Office/80MHz/3mo/m3/CSI_pcap -> 4 arquivos, Total: 1,7GB, Média: 428MB ../Data/coarse/Office/80MHz/3mo/m1/CSI_pcap -> 4 arquivos, Total: 1,7GB, Média: 432MB ../Data/proximity/Classroom/80MHz/3mo/m2/CSI_pcap -> 20 arquivos, Total: 14GB, Média: 704MB ../Data/proximity/Classroom/80MHz/3mo/m3/CSI_pcap -> 20 arquivos, Total: 15GB, Média: 727MB ../Data/proximity/Classroom/80MHz/3mo/m1/CSI_pcap -> 20 arquivos, Total: 14GB, Média: 710MB ../Data/proximity/Office/80MHz/3mo/m2/CSI_pcap -> 20 arquivos, Total: 23GB, Média: 1,2GB ../Data/proximity/Office/80MHz/3mo/m3/CSI_pcap -> 20 arquivos, Total: 22GB, Média: 1,1GB ../Data/proximity/Office/80MHz/3mo/m1/CSI_pcap -> 20 arquivos, Total: 22GB, Média: 1,1GB ../Data/fine_grained/Classroom/80MHz/3mo/m2/CSI_pcap -> 20 arquivos, Total: 14GB, Média: 704MB ../Data/fine_grained/Classroom/80MHz/3mo/m3/CSI_pcap -> 20 arquivos, Total: 15GB, Média: 727MB ../Data/fine_grained/Classroom/80MHz/3mo/m1/CSI_pcap -> 20 arquivos, Total: 14GB, Média: 710MB ../Data/fine_grained/Office/80MHz/3mo/m2/CSI_pcap -> 20 arquivos, Total: 23GB, Média: 1,2GB ../Data/fine_grained/Office/80MHz/3mo/m3/CSI_pcap -> 20 arquivos, Total: 22GB, Média: 1,1GB ../Data/fine_grained/Office/80MHz/3mo/m1/CSI_pcap -> 20 arquivos, Total: 22GB, Média: 1,1GB
Observações¶
- Nos testes proximity e fine_grained, há 20 arquivos PCAP nomeados de A.pcap a T.pcap. (20 atividades)
- No teste coarse, existem apenas 4 arquivos PCAP (A.pcap a D.pcap), o que sugere que o modelo de identificação dos indivÃduos não precisou ser treinado com todas as atividades.
- O tamanho dos arquivos PCAP varia entre os testes, o que possivelmente reflete diferenças no tempo de captura dos dados.
- No total são 264 arquivos PCAP.
- 120 proximity
- 24 coarse
- 129 fine_grained
# Setup
import os
import pandas as pd
import numpy as np
import h5py
import scipy.io
import string
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
import matplotlib.animation as animation
import matplotlib as mpl
import seaborn as sns
from scapy.all import RawPcapReader
from datetime import datetime
from pathlib import Path
from tqdm import tqdm
from sklearn.preprocessing import MinMaxScaler
from sklearn.manifold import TSNE
from sklearn.preprocessing import LabelEncoder
# Função para resumir arquivos PCAP
def summarize_pcap(file_path, verbose=False):
file_size_bytes = os.path.getsize(file_path)
reader = RawPcapReader(file_path)
num_packets = 0
start_time = None
end_time = None
for pkt_data, pkt_metadata in reader:
ts = pkt_metadata.sec + pkt_metadata.usec / 1_000_000
if start_time is None:
start_time = ts
end_time = ts
num_packets += 1
reader.close()
start_dt = datetime.fromtimestamp(start_time)
end_dt = datetime.fromtimestamp(end_time)
duration = end_time - start_time
file_size_mb = file_size_bytes / (1024 * 1024) # Convert bytes to megabytes
if verbose:
print("📄 PCAP Summary:")
print(f"- Number of packets: {num_packets}")
print(f"- Start time : {start_dt}")
print(f"- End time : {end_dt}")
print(f"- Duration : {duration:.6f} seconds")
print(f"- File size : {file_size_mb:.2f} MB")
return (num_packets, start_dt, end_dt, duration, file_size_mb)
# Exemplo de uso
file_path = "../Data/coarse/Classroom/80MHz/3mo/m2/CSI_pcap/A.pcap"
num_packets, start_dt, end_dt, duration, file_size_mb = summarize_pcap(file_path, verbose=True)
📄 PCAP Summary: - Number of packets: 400604 - Start time : 2018-05-05 04:41:20.467729 - End time : 2018-05-05 04:46:30.719364 - Duration : 310.251635 seconds - File size : 420.25 MB
# Extraindo resumo de todos os arquivos PCAP
# Salvando os resultados em um dicionário df.to_csv('SAIDAS/01-pcap_summary.csv', index=False)
def summarize_all_pcaps(output_file='SAIDAS/01-pcap_summary.csv'):
if os.path.exists(output_file):
return pd.read_csv('SAIDAS/01-pcap_summary.csv')
else:
df_proto = {
'file_path': [],
'num_packets': [],
'start_time': [],
'end_time': [],
'duration': [],
'file_size_mb': []
}
file_paths = Path('../Data').rglob('*.pcap')
for file_path in tqdm(sorted(file_paths)):
file_path = str(file_path)
num_packets, start_dt, end_dt, duration, file_size_mb = summarize_pcap(file_path)
df_proto['file_path'].append(file_path)
df_proto['num_packets'].append(num_packets)
df_proto['start_time'].append(start_dt)
df_proto['end_time'].append(end_dt)
df_proto['duration'].append(duration)
df_proto['file_size_mb'].append(file_size_mb)
return pd.DataFrame(df_proto).to_csv('SAIDAS/01-pcap_summary.csv', index=False)
pcap_summary = summarize_all_pcaps()
pcap_summary.head()
| file_path | num_packets | start_time | end_time | duration | file_size_mb | test | environment | monitor | activity | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ../Data/coarse/Classroom/80MHz/3mo/m1/CSI_pcap... | 397780 | 2018-05-05 04:08:53.974579 | 2018-05-05 04:14:04.204180 | 310.229601 | 417.287849 | coarse | Classroom | m1 | A |
| 1 | ../Data/coarse/Classroom/80MHz/3mo/m1/CSI_pcap... | 390882 | 2018-05-05 04:17:39.777768 | 2018-05-05 04:22:50.032895 | 310.255127 | 410.051559 | coarse | Classroom | m1 | B |
| 2 | ../Data/coarse/Classroom/80MHz/3mo/m1/CSI_pcap... | 402670 | 2018-05-05 04:33:40.558963 | 2018-05-05 04:38:50.808146 | 310.249183 | 422.417664 | coarse | Classroom | m1 | C |
| 3 | ../Data/coarse/Classroom/80MHz/3mo/m1/CSI_pcap... | 409930 | 2018-05-05 04:25:53.864638 | 2018-05-05 04:31:04.118338 | 310.253700 | 430.033707 | coarse | Classroom | m1 | D |
| 4 | ../Data/coarse/Classroom/80MHz/3mo/m2/CSI_pcap... | 400604 | 2018-05-05 04:41:20.467729 | 2018-05-05 04:46:30.719364 | 310.251635 | 420.250343 | coarse | Classroom | m2 | A |
# Resumo dos arquivos PCAP
print(f'Total de arquivos PCAP: {len(pcap_summary)} ({pcap_summary["file_size_mb"].sum():.2f} MB)')
print()
print(f'Total de pacotes: {pcap_summary["num_packets"].sum()} ({pcap_summary["duration"].sum()/60:.2f} minutos)')
print()
print(f'InÃcio da captura: {pcap_summary["start_time"].min()}')
print(f' Fim da captura: {pcap_summary["end_time"].max()}')
Total de arquivos PCAP: 264 (229664.58 MB) Total de pacotes: 218927963 (3420.30 minutos) InÃcio da captura: 2018-05-05 02:18:01.914463 Fim da captura: 2018-05-05 13:48:44.733418
def plot_duration_by_activity_and_test(df):
plt.figure(figsize=(12, 6))
sns.barplot(x='activity', y='duration', hue='test', data=df, estimator='mean')
plt.xticks(rotation=45)
plt.title('Mean Duration by Activity and Test')
plt.xlabel('Activity')
plt.ylabel('Mean Duration')
plt.tight_layout()
plt.gca().yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, _: f"{int(x // 60)}' {int(x % 60)}''"))
plot_duration_by_activity_and_test(pcap_summary)
Esclarecendo a diferença no dataset Coarse¶
É o modelo utilizado para identificar a pessoa.
Aqui as classes são:
- A - Pessoa 1
- B - Pessoa 2
- C - Pessoa 3
- D - Sem atividade
3. Extração do CSI dos arquivos PCAP¶
O primeiro passo do pré-processamento é a extração a informação de CSI dos arquivos PCAP.
A extração é realizada executando o script CSI_extractor_SimWiSense.m, localizado no diretório SiMWiSense/Matlab_code/.
Antes de rodar o script, é necessário alterar o campo Test="xxxx" para o nome do teste desejado. Para extrair os dados de todos os três testes do conjunto, é necessário executar o script separadamente para:
Test="proximity"Test="coarse"Test="fine_grained"
Pontos Importantes¶
CSI (Channel State Information) refere-se às informações do estado do canal, fundamentais para estimativas e equalizações no Wi-Fi.
Cada amostra de CSI contém dois valores (amplitude e fase) para cada subportadora. No código, esses valores são representados como números complexos.
A modulação Wi-Fi (no padrão utilizado) divide o sinal em subportadoras ortogonais. Para o canal de 80 MHz de largura de banda, temos 256 subportadoras no total.
Entretanto, apenas as subportadoras efetivamente usadas para transmissão de dados são consideradas. No código, são selecionadas 242 subportadoras (da 7 à 128 e da 132 à 251), descartando subportadoras do tipo null e guard.
Portanto, cada amostra de CSI em um instante **t contém 242 números complexos**.
A quantidade de amostras extraÃdas de um PCAP está relacionada ao número de pacotes capturados (isto é, à duração da gravação).
Como visto anteriormente, temos 264 arquivos PCAP no total, e este processo irá gerar exatamente 264 arquivos
.mat, contendo as extrações de CSI em formato de matrizes do MATLAB.Os arquivos
.matgerados são ainda maiores do que os arquivos PCAP originais.O código de extração filtra pacotes com base no chip de Wi-Fi utilizado. A maneira de extrair depende do chip. Para extrair o CSI de dentro dos pacotes, é utilizada uma função em C chamada
unpack_float_acphy, vem de um exemplo do NexMon.
def summarize_mat_files(output_file='SAIDAS/02-mat_summary.csv'):
if os.path.exists(output_file):
return pd.read_csv('SAIDAS/02-mat_summary.csv')
else:
def getMinMax(mat_file_path):
with h5py.File(mat_file_path, 'r') as f:
csi_data = f['csi'][:]
real = csi_data['real']
imag = csi_data['imag']
min_real = np.min(real)
max_real = np.max(real)
min_imag = np.min(imag)
max_imag = np.max(imag)
min_real_subcarriers = np.min(real, axis=1)
max_real_subcarriers = np.max(real, axis=1)
min_imag_subcarriers = np.min(imag, axis=1)
max_imag_subcarriers = np.max(imag, axis=1)
return min_real, max_real, min_imag, max_imag, csi_data.shape[0], csi_data.shape[1], min_real_subcarriers, max_real_subcarriers, min_imag_subcarriers, max_imag_subcarriers
df_proto = {
'file_path': [],
'min_real': [],
'max_real': [],
'min_imag': [],
'max_imag': [],
'shape0': [],
'shape1': []
}
for i in range(1, 243):
df_proto[f'min_real_subcarrier_{i}'] = []
df_proto[f'max_real_subcarrier_{i}'] = []
df_proto[f'min_imag_subcarrier_{i}'] = []
df_proto[f'max_imag_subcarrier_{i}'] = []
file_paths = Path('../Data').rglob('*.mat')
file_paths = [p for p in Path('../Data').rglob('*.mat') if 'Slot' not in str(p)]
for file_path in tqdm(sorted(file_paths)):
file_path = str(file_path)
min_real, max_real, min_imag, max_imag, shape0, shape1, min_real_subcarriers, max_real_subcarriers, min_imag_subcarriers, max_imag_subcarriers = getMinMax(file_path)
df_proto['file_path'].append(file_path)
df_proto['min_real'].append(min_real)
df_proto['max_real'].append(max_real)
df_proto['min_imag'].append(min_imag)
df_proto['max_imag'].append(max_imag)
df_proto['shape0'].append(shape0)
df_proto['shape1'].append(shape1)
for i in range(1,243):
df_proto[f'min_real_subcarrier_{i}'].append(min_real_subcarriers[i-1])
df_proto[f'max_real_subcarrier_{i}'].append(max_real_subcarriers[i-1])
df_proto[f'min_imag_subcarrier_{i}'].append(min_imag_subcarriers[i-1])
df_proto[f'max_imag_subcarrier_{i}'].append(max_imag_subcarriers[i-1])
df = pd.DataFrame(df_proto)
df.to_csv('SAIDAS/02-mat_summary.csv', index=False)
return df
mat_summary = summarize_mat_files()
mat_summary.head()
| file_path | min_real | max_real | min_imag | max_imag | shape0 | shape1 | min_real_subcarrier_1 | max_real_subcarrier_1 | min_imag_subcarrier_1 | ... | min_imag_subcarrier_240 | max_imag_subcarrier_240 | min_real_subcarrier_241 | max_real_subcarrier_241 | min_imag_subcarrier_241 | max_imag_subcarrier_241 | min_real_subcarrier_242 | max_real_subcarrier_242 | min_imag_subcarrier_242 | max_imag_subcarrier_242 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ../Data/coarse/Classroom/80MHz/3mo/m1/A/A.mat | -2046.0 | 2037.0 | -2032.0 | 2043.0 | 242 | 397780 | -1883.0 | 1818.0 | -1816.0 | ... | -1005.0 | 1020.0 | -1113.0 | 1108.0 | -1115.0 | 1095.0 | -1169.0 | 1186.0 | -1182.0 | 1178.0 |
| 1 | ../Data/coarse/Classroom/80MHz/3mo/m1/B/B.mat | -2047.0 | 2046.0 | -2046.0 | 2047.0 | 242 | 390882 | -1741.0 | 1770.0 | -1811.0 | ... | -1805.0 | 1826.0 | -1432.0 | 1226.0 | -1919.0 | 1917.0 | -1739.0 | 1409.0 | -1996.0 | 1987.0 |
| 2 | ../Data/coarse/Classroom/80MHz/3mo/m1/C/C.mat | -2047.0 | 2047.0 | -2047.0 | 2047.0 | 242 | 402670 | -1880.0 | 1919.0 | -1523.0 | ... | -1660.0 | 1601.0 | -1549.0 | 1571.0 | -1495.0 | 1525.0 | -1376.0 | 1411.0 | -1379.0 | 1402.0 |
| 3 | ../Data/coarse/Classroom/80MHz/3mo/m1/D/D.mat | -2046.0 | 2047.0 | -2046.0 | 2047.0 | 242 | 409930 | -1559.0 | 1801.0 | -1484.0 | ... | -772.0 | 752.0 | -741.0 | 677.0 | -691.0 | 625.0 | -634.0 | 552.0 | -588.0 | 514.0 |
| 4 | ../Data/coarse/Classroom/80MHz/3mo/m2/A/A.mat | -2047.0 | 2047.0 | -2047.0 | 2047.0 | 242 | 400604 | -1721.0 | 1329.0 | -1325.0 | ... | -1424.0 | 1465.0 | -1529.0 | 1427.0 | -1422.0 | 1481.0 | -1545.0 | 1446.0 | -1453.0 | 1471.0 |
5 rows × 975 columns
print(f'Total de arquivos MAT: {len(mat_summary)}')
print(f'Total de amostras: {mat_summary["shape1"].sum()}')
print(f'Total de subportadoras: {mat_summary["shape0"].max()}')
print()
print('Valores mÃnimos e máximos:')
print(f'Real: [{mat_summary["min_real"].min()}, {mat_summary["max_real"].max()}]')
print(f'Iaginário [{mat_summary["min_imag"].min()}, {mat_summary["max_imag"].max()}]')
Total de arquivos MAT: 264 Total de amostras: 218927963 Total de subportadoras: 242 Valores mÃnimos e máximos: Real: [-2047.0, 2047.0] Iaginário [-2047.0, 2047.0]
min_real = []
max_real = []
min_imag = []
max_imag = []
print('Valores mÃnimos e máximos para cada subportadora:')
for subcarrier in range(1, 243):
print(f'Subportadora {subcarrier:3}: Real: [{mat_summary[f"min_real_subcarrier_{subcarrier}"].min():4}, {mat_summary[f"max_real_subcarrier_{subcarrier}"].max()}] Imaginário [{mat_summary[f"min_imag_subcarrier_{subcarrier}"].min()}, {mat_summary[f"max_imag_subcarrier_{subcarrier}"].max()}]')
min_real.append(mat_summary[f'min_real_subcarrier_{subcarrier}'].min())
max_real.append(mat_summary[f'max_real_subcarrier_{subcarrier}'].max())
min_imag.append(mat_summary[f'min_imag_subcarrier_{subcarrier}'].min())
max_imag.append(mat_summary[f'max_imag_subcarrier_{subcarrier}'].max())
Valores mÃnimos e máximos para cada subportadora: Subportadora 1: Real: [-2045.0, 2047.0] Imaginário [-2045.0, 2047.0] Subportadora 2: Real: [-2046.0, 2031.0] Imaginário [-2040.0, 2038.0] Subportadora 3: Real: [-2047.0, 2031.0] Imaginário [-2046.0, 2042.0] Subportadora 4: Real: [-2038.0, 2047.0] Imaginário [-2041.0, 2034.0] Subportadora 5: Real: [-2046.0, 2046.0] Imaginário [-2044.0, 2047.0] Subportadora 6: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 7: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 8: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 9: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 10: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 11: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 12: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 13: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 14: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 15: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 16: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 17: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 18: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2046.0] Subportadora 19: Real: [-2044.0, 2041.0] Imaginário [-2044.0, 2046.0] Subportadora 20: Real: [-2043.0, 2043.0] Imaginário [-2038.0, 2039.0] Subportadora 21: Real: [-2046.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 22: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 23: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 24: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 25: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 26: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 27: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 28: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 29: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 30: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 31: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 32: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 33: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 34: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 35: Real: [-2047.0, 2042.0] Imaginário [-2045.0, 2047.0] Subportadora 36: Real: [-2045.0, 2042.0] Imaginário [-2044.0, 2046.0] Subportadora 37: Real: [-2041.0, 2045.0] Imaginário [-2045.0, 2046.0] Subportadora 38: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 39: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 40: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 41: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 42: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 43: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 44: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 45: Real: [-2047.0, 2046.0] Imaginário [-2047.0, 2047.0] Subportadora 46: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 47: Real: [-2047.0, 2047.0] Imaginário [-2046.0, 2047.0] Subportadora 48: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 49: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 50: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 51: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 52: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 53: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 54: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 55: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 56: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 57: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 58: Real: [-2047.0, 2046.0] Imaginário [-2047.0, 2047.0] Subportadora 59: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 60: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 61: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 62: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 63: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 64: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 65: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 66: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 67: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 68: Real: [-2046.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 69: Real: [-2044.0, 2045.0] Imaginário [-2046.0, 2046.0] Subportadora 70: Real: [-2041.0, 2034.0] Imaginário [-2039.0, 2044.0] Subportadora 71: Real: [-2029.0, 2033.0] Imaginário [-2035.0, 2047.0] Subportadora 72: Real: [-2038.0, 2030.0] Imaginário [-2032.0, 2043.0] Subportadora 73: Real: [-2037.0, 2043.0] Imaginário [-2046.0, 2042.0] Subportadora 74: Real: [-2041.0, 2046.0] Imaginário [-2047.0, 2041.0] Subportadora 75: Real: [-2044.0, 2045.0] Imaginário [-2046.0, 2046.0] Subportadora 76: Real: [-2046.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 77: Real: [-2046.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 78: Real: [-2047.0, 2047.0] Imaginário [-2045.0, 2046.0] Subportadora 79: Real: [-2046.0, 2046.0] Imaginário [-2047.0, 2047.0] Subportadora 80: Real: [-2042.0, 2040.0] Imaginário [-2043.0, 2042.0] Subportadora 81: Real: [-2043.0, 2031.0] Imaginário [-2023.0, 2028.0] Subportadora 82: Real: [-2007.0, 2002.0] Imaginário [-2042.0, 2011.0] Subportadora 83: Real: [-1974.0, 1979.0] Imaginário [-2021.0, 2028.0] Subportadora 84: Real: [-1924.0, 1935.0] Imaginário [-2014.0, 2016.0] Subportadora 85: Real: [-1868.0, 1930.0] Imaginário [-1951.0, 1930.0] Subportadora 86: Real: [-1782.0, 1884.0] Imaginário [-1878.0, 1863.0] Subportadora 87: Real: [-1716.0, 1750.0] Imaginário [-1885.0, 1876.0] Subportadora 88: Real: [-1715.0, 1679.0] Imaginário [-1884.0, 1758.0] Subportadora 89: Real: [-1661.0, 1675.0] Imaginário [-1877.0, 1765.0] Subportadora 90: Real: [-1666.0, 1589.0] Imaginário [-1884.0, 1760.0] Subportadora 91: Real: [-1855.0, 1664.0] Imaginário [-1692.0, 1738.0] Subportadora 92: Real: [-1679.0, 1695.0] Imaginário [-1885.0, 1761.0] Subportadora 93: Real: [-1779.0, 1747.0] Imaginário [-1878.0, 1765.0] Subportadora 94: Real: [-1802.0, 1779.0] Imaginário [-1874.0, 1854.0] Subportadora 95: Real: [-1854.0, 1855.0] Imaginário [-1983.0, 1998.0] Subportadora 96: Real: [-1904.0, 1911.0] Imaginário [-1944.0, 1900.0] Subportadora 97: Real: [-1869.0, 1927.0] Imaginário [-1877.0, 1917.0] Subportadora 98: Real: [-1884.0, 1877.0] Imaginário [-1889.0, 1847.0] Subportadora 99: Real: [-1932.0, 2001.0] Imaginário [-1877.0, 1849.0] Subportadora 100: Real: [-2000.0, 2042.0] Imaginário [-2031.0, 1902.0] Subportadora 101: Real: [-2010.0, 1950.0] Imaginário [-1969.0, 2042.0] Subportadora 102: Real: [-1886.0, 1883.0] Imaginário [-1890.0, 2022.0] Subportadora 103: Real: [-1921.0, 1849.0] Imaginário [-1870.0, 1976.0] Subportadora 104: Real: [-1836.0, 1816.0] Imaginário [-1887.0, 1874.0] Subportadora 105: Real: [-1788.0, 1816.0] Imaginário [-1870.0, 1805.0] Subportadora 106: Real: [-1761.0, 1758.0] Imaginário [-1877.0, 1772.0] Subportadora 107: Real: [-1704.0, 1962.0] Imaginário [-1879.0, 1760.0] Subportadora 108: Real: [-1762.0, 1698.0] Imaginário [-1868.0, 1761.0] Subportadora 109: Real: [-1724.0, 1692.0] Imaginário [-1876.0, 1766.0] Subportadora 110: Real: [-1718.0, 1677.0] Imaginário [-1877.0, 1759.0] Subportadora 111: Real: [-1662.0, 1612.0] Imaginário [-1885.0, 1766.0] Subportadora 112: Real: [-1627.0, 1538.0] Imaginário [-1881.0, 1761.0] Subportadora 113: Real: [-1644.0, 1504.0] Imaginário [-1879.0, 1765.0] Subportadora 114: Real: [-1645.0, 1417.0] Imaginário [-1874.0, 1759.0] Subportadora 115: Real: [-1656.0, 1400.0] Imaginário [-1892.0, 1766.0] Subportadora 116: Real: [-1657.0, 1517.0] Imaginário [-1877.0, 1766.0] Subportadora 117: Real: [-1654.0, 1670.0] Imaginário [-1881.0, 1777.0] Subportadora 118: Real: [-771.0, 1954.0] Imaginário [-972.0, 415.0] Subportadora 119: Real: [-398.0, 867.0] Imaginário [-671.0, 815.0] Subportadora 120: Real: [-879.0, 505.0] Imaginário [-815.0, 951.0] Subportadora 121: Real: [-807.0, 503.0] Imaginário [-351.0, 562.0] Subportadora 122: Real: [-327.0, 518.0] Imaginário [-484.0, 239.0] Subportadora 123: Real: [-411.0, 505.0] Imaginário [-503.0, 244.0] Subportadora 124: Real: [-545.0, 506.0] Imaginário [-618.0, 331.0] Subportadora 125: Real: [-1131.0, 999.0] Imaginário [-967.0, 1869.0] Subportadora 126: Real: [-1957.0, 1974.0] Imaginário [-1948.0, 1932.0] Subportadora 127: Real: [-1943.0, 1986.0] Imaginário [-1956.0, 2015.0] Subportadora 128: Real: [-1848.0, 1886.0] Imaginário [-1898.0, 1872.0] Subportadora 129: Real: [-1845.0, 1795.0] Imaginário [-1861.0, 1885.0] Subportadora 130: Real: [-1894.0, 1863.0] Imaginário [-1890.0, 1868.0] Subportadora 131: Real: [-1857.0, 1907.0] Imaginário [-1859.0, 1818.0] Subportadora 132: Real: [-1916.0, 1937.0] Imaginário [-1892.0, 1896.0] Subportadora 133: Real: [-1910.0, 1958.0] Imaginário [-1935.0, 1846.0] Subportadora 134: Real: [-1857.0, 1882.0] Imaginário [-1929.0, 1900.0] Subportadora 135: Real: [-1979.0, 1973.0] Imaginário [-1899.0, 1962.0] Subportadora 136: Real: [-1992.0, 1934.0] Imaginário [-1933.0, 1982.0] Subportadora 137: Real: [-2002.0, 1951.0] Imaginário [-1965.0, 1960.0] Subportadora 138: Real: [-2026.0, 1943.0] Imaginário [-1953.0, 1993.0] Subportadora 139: Real: [-1961.0, 2007.0] Imaginário [-2046.0, 2036.0] Subportadora 140: Real: [-1961.0, 1961.0] Imaginário [-1976.0, 1992.0] Subportadora 141: Real: [-2002.0, 1975.0] Imaginário [-2022.0, 2018.0] Subportadora 142: Real: [-2003.0, 1979.0] Imaginário [-2018.0, 2024.0] Subportadora 143: Real: [-2009.0, 1998.0] Imaginário [-2001.0, 2016.0] Subportadora 144: Real: [-2009.0, 2020.0] Imaginário [-2035.0, 2029.0] Subportadora 145: Real: [-2020.0, 2036.0] Imaginário [-2042.0, 2044.0] Subportadora 146: Real: [-2045.0, 2047.0] Imaginário [-2044.0, 2042.0] Subportadora 147: Real: [-2047.0, 2046.0] Imaginário [-2045.0, 2046.0] Subportadora 148: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 149: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 150: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 151: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 152: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 153: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 154: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 155: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 156: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 157: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 158: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 159: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 160: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 161: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 162: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 163: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 164: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 165: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 166: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 167: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 168: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 169: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 170: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 171: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2046.0] Subportadora 172: Real: [-2047.0, 2047.0] Imaginário [-2046.0, 2045.0] Subportadora 173: Real: [-2044.0, 2042.0] Imaginário [-2046.0, 2046.0] Subportadora 174: Real: [-2032.0, 2033.0] Imaginário [-2040.0, 2044.0] Subportadora 175: Real: [-2041.0, 2042.0] Imaginário [-1983.0, 2028.0] Subportadora 176: Real: [-2022.0, 2000.0] Imaginário [-1974.0, 1994.0] Subportadora 177: Real: [-1972.0, 1968.0] Imaginário [-1941.0, 1916.0] Subportadora 178: Real: [-1901.0, 1932.0] Imaginário [-1929.0, 1873.0] Subportadora 179: Real: [-1875.0, 1909.0] Imaginário [-1919.0, 1932.0] Subportadora 180: Real: [-1993.0, 1982.0] Imaginário [-1959.0, 1977.0] Subportadora 181: Real: [-2039.0, 2039.0] Imaginário [-2033.0, 2040.0] Subportadora 182: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 183: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 184: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 185: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 186: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 187: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 188: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 189: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 190: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 191: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 192: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 193: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 194: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 195: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 196: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 197: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 198: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 199: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 200: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 201: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 202: Real: [-2047.0, 2047.0] Imaginário [-2046.0, 2045.0] Subportadora 203: Real: [-2047.0, 2044.0] Imaginário [-2047.0, 2047.0] Subportadora 204: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 205: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 206: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 207: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 208: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 209: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 210: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 211: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 212: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 213: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 214: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 215: Real: [-2047.0, 2047.0] Imaginário [-2046.0, 2047.0] Subportadora 216: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2046.0] Subportadora 217: Real: [-2045.0, 2045.0] Imaginário [-2047.0, 2040.0] Subportadora 218: Real: [-2027.0, 2046.0] Imaginário [-2037.0, 2046.0] Subportadora 219: Real: [-2024.0, 2029.0] Imaginário [-2034.0, 2021.0] Subportadora 220: Real: [-2025.0, 2037.0] Imaginário [-2032.0, 2018.0] Subportadora 221: Real: [-2044.0, 2042.0] Imaginário [-2039.0, 2037.0] Subportadora 222: Real: [-2046.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 223: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 224: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 225: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 226: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 227: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 228: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 229: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 230: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 231: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 232: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 233: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 234: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 235: Real: [-2047.0, 2047.0] Imaginário [-2047.0, 2047.0] Subportadora 236: Real: [-2036.0, 2043.0] Imaginário [-2043.0, 2039.0] Subportadora 237: Real: [-2041.0, 2042.0] Imaginário [-2032.0, 2039.0] Subportadora 238: Real: [-2032.0, 2042.0] Imaginário [-2040.0, 2040.0] Subportadora 239: Real: [-2039.0, 2041.0] Imaginário [-2039.0, 2028.0] Subportadora 240: Real: [-2031.0, 2047.0] Imaginário [-2047.0, 2045.0] Subportadora 241: Real: [-2044.0, 2042.0] Imaginário [-2039.0, 2044.0] Subportadora 242: Real: [-2046.0, 2042.0] Imaginário [-2044.0, 2047.0]
import numpy as np
def plot_intervalos_min_max_subportadoras(min_real, max_real, min_imag, max_imag):
fig, ax = plt.subplots(figsize=(12, 6))
subcarriers = np.arange(1, 243) # Subportadoras de 1 a 242
# Plotando os intervalos
ax.fill_between(subcarriers, min_real, max_real, color='red', alpha=0.3, label='Real')
ax.fill_between(subcarriers, min_imag, max_imag, color='green', alpha=0.3, label='Imaginário')
# Configurando o gráfico
ax.set_title('Intervalos MÃnimos e Máximos para cada Subportadora')
ax.set_xlabel('Subportadora')
ax.set_ylabel('Valor')
ax.legend()
plt.grid()
plt.show()
plot_intervalos_min_max_subportadoras(min_real, max_real, min_imag, max_imag)
Ponto importante¶
algumas subportadoras tem intervalo bem diferente. Nesses casos talvez seja interessante reescalar o valor para facilitar o gradiente descendente.
Subportadora 118: Real: [-771.0, 1954.0] Imaginário [-972.0, 415.0]
Subportadora 119: Real: [-398.0, 867.0] Imaginário [-671.0, 815.0]
Subportadora 120: Real: [-879.0, 505.0] Imaginário [-815.0, 951.0]
Subportadora 121: Real: [-807.0, 503.0] Imaginário [-351.0, 562.0]
Subportadora 122: Real: [-327.0, 518.0] Imaginário [-484.0, 239.0]
Subportadora 123: Real: [-411.0, 505.0] Imaginário [-503.0, 244.0]
Subportadora 124: Real: [-545.0, 506.0] Imaginário [-618.0, 331.0]
Subportadora 125: Real: [-1131.0, 999.0] Imaginário [-967.0, 1869.0]
mpl.rcParams['animation.embed_limit'] = 30 * 1024 * 1024 # 30 MB
def plot_mat(mat_file_name, window_size=1000, step=100, output_dir='./SAIDAS', n_samples=100000):
if os.path.exists(output_file):
print(f'Arquivo {output_file} já existe. Pulando...')
return
with h5py.File(mat_file_name, 'r') as f:
data = f['csi'][:]
file_path_splited = mat_file_name.split('/')
test = file_path_splited[2]
environment = file_path_splited[3]
monitor = file_path_splited[6]
activity = file_path_splited[8].split('.')[0]
output_file = f'{output_dir}/02-espectograma_{test}_{environment}_{monitor}_{activity}.mp4'
matrix = data.T[:n_samples,:]
amplitude = matrix['real']
phase = matrix['imag']
combined = np.sqrt(amplitude**2 + phase**2)
frames = (len(amplitude) - window_size) // step
# Configurando a figura
fig, ax = plt.subplots(figsize=(3, 6))
heatmap = ax.imshow(combined[0:window_size].T,
aspect='auto', cmap='viridis',
origin='lower',
extent=[0, window_size, 0, 241])
ax.set_xlabel('Tempo (janela de amostras)')
ax.set_ylabel('Subportadoras')
titulo = f'{test} {environment} {monitor} {activity}'
title = ax.set_title(titulo)
# Função de atualização
def update(frame):
start = frame * step
end = start + window_size
data = combined[start:end].T
heatmap.set_data(data)
heatmap.set_extent([start, end, 0, 241])
return heatmap, title
# Criando a animação
ani = animation.FuncAnimation(fig, update, frames=frames, interval=100, blit=True)
ani.save(output_file, writer='ffmpeg', fps=30)
mats = [
'../Data/fine_grained/Classroom/80MHz/3mo/m2/A/A.mat',
'../Data/fine_grained/Classroom/80MHz/3mo/m2/B/B.mat',
'../Data/fine_grained/Classroom/80MHz/3mo/m2/C/C.mat'
]
for mat_file_name in mats:
plot_mat(mat_file_name, n_samples=40000, window_size=250, step=50, output_dir='./SAIDAS')
!ffmpeg -y -i SAIDAS/02-espectograma_fine_grained_Classroom_m2_A.mp4 -i SAIDAS/02-espectograma_fine_grained_Classroom_m2_B.mp4 -i SAIDAS/02-espectograma_fine_grained_Classroom_m2_C.mp4 -filter_complex "hstack=inputs=3" SAIDAS/02-espectograma_fine_grained_Classroom_m2_ABC.mp4
ffmpeg version 6.1.1-3ubuntu5+esm2 Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 13 (Ubuntu 13.2.0-23ubuntu4)
configuration: --prefix=/usr --extra-version=3ubuntu5+esm2 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --disable-omx --enable-gnutls --enable-libaom --enable-libass --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libharfbuzz --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-openal --enable-opencl --enable-opengl --disable-sndio --enable-libvpl --disable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-ladspa --enable-libbluray --enable-libjack --enable-libpulse --enable-librabbitmq --enable-librist --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libx264 --enable-libzmq --enable-libzvbi --enable-lv2 --enable-sdl2 --enable-libplacebo --enable-librav1e --enable-pocketsphinx --enable-librsvg --enable-libjxl --enable-shared
WARNING: library configuration mismatch
avcodec configuration: --prefix=/usr --extra-version=3ubuntu5+esm2 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --disable-omx --enable-gnutls --enable-libaom --enable-libass --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libharfbuzz --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-openal --enable-opencl --enable-opengl --disable-sndio --enable-libvpl --disable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-ladspa --enable-libbluray --enable-libjack --enable-libpulse --enable-librabbitmq --enable-librist --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libx264 --enable-libzmq --enable-libzvbi --enable-lv2 --enable-sdl2 --enable-libplacebo --enable-librav1e --enable-pocketsphinx --enable-librsvg --enable-libjxl --enable-shared --enable-version3 --disable-doc --disable-programs --disable-static --enable-libaribb24 --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libtesseract --enable-libvo_amrwbenc --enable-libsmbclient
libavutil 58. 29.100 / 58. 29.100
libavcodec 60. 31.102 / 60. 31.102
libavformat 60. 16.100 / 60. 16.100
libavdevice 60. 3.100 / 60. 3.100
libavfilter 9. 12.100 / 9. 12.100
libswscale 7. 5.100 / 7. 5.100
libswresample 4. 12.100 / 4. 12.100
libpostproc 57. 3.100 / 57. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'SAIDAS/02-espectograma_fine_grained_Classroom_m2_A.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf60.16.100
Duration: 00:00:26.50, start: 0.000000, bitrate: 546 kb/s
Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 300x600, 544 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc60.31.102 libx264
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'SAIDAS/02-espectograma_fine_grained_Classroom_m2_B.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf60.16.100
Duration: 00:00:26.50, start: 0.000000, bitrate: 414 kb/s
Stream #1:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 300x600, 411 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc60.31.102 libx264
Input #2, mov,mp4,m4a,3gp,3g2,mj2, from 'SAIDAS/02-espectograma_fine_grained_Classroom_m2_C.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf60.16.100
Duration: 00:00:26.50, start: 0.000000, bitrate: 568 kb/s
Stream #2:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 300x600, 566 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc60.31.102 libx264
Stream mapping:
Stream #0:0 (h264) -> hstack
Stream #1:0 (h264) -> hstack
Stream #2:0 (h264) -> hstack
hstack:default -> Stream #0:0 (libx264)
Press [q] to stop, [?] for help
[libx264 @ 0x59fd61ed4700] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x59fd61ed4700] profile High, level 3.1, 4:2:0, 8-bit
[libx264 @ 0x59fd61ed4700] 264 - core 164 r3108 31e19f9 - H.264/MPEG-4 AVC codec - Copyleft 2003-2023 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=19 lookahead_threads=3 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'SAIDAS/02-espectograma_fine_grained_Classroom_m2_ABC.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf60.16.100
Stream #0:0: Video: h264 (avc1 / 0x31637661), yuv420p(progressive), 900x600, q=2-31, 30 fps, 15360 tbn
Metadata:
encoder : Lavc60.31.102 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
[out#0/mp4 @ 0x59fd61ed3480] video:4856kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.204926%
frame= 795 fps=383 q=-1.0 Lsize= 4865kB time=00:00:26.40 bitrate=1509.8kbits/s speed=12.7x
[libx264 @ 0x59fd61ed4700] frame I:4 Avg QP:23.16 size: 29728
[libx264 @ 0x59fd61ed4700] frame P:380 Avg QP:26.81 size: 7779
[libx264 @ 0x59fd61ed4700] frame B:411 Avg QP:28.22 size: 4614
[libx264 @ 0x59fd61ed4700] consecutive B-frames: 9.1% 65.9% 0.4% 24.7%
[libx264 @ 0x59fd61ed4700] mb I I16..4: 51.9% 31.4% 16.7%
[libx264 @ 0x59fd61ed4700] mb P I16..4: 14.7% 3.8% 1.7% P16..4: 22.3% 9.0% 2.4% 0.0% 0.0% skip:46.1%
[libx264 @ 0x59fd61ed4700] mb B I16..4: 6.0% 0.8% 0.4% B16..8: 26.1% 7.4% 0.5% direct: 1.8% skip:57.0% L0:52.1% L1:43.0% BI: 4.9%
[libx264 @ 0x59fd61ed4700] 8x8 transform intra:17.0% inter:92.2%
[libx264 @ 0x59fd61ed4700] coded y,uvDC,uvAC intra: 26.0% 90.0% 55.4% inter: 11.4% 21.0% 6.3%
[libx264 @ 0x59fd61ed4700] i16 v,h,dc,p: 93% 4% 0% 2%
[libx264 @ 0x59fd61ed4700] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 58% 19% 16% 1% 1% 1% 2% 1% 2%
[libx264 @ 0x59fd61ed4700] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 84% 6% 7% 0% 0% 0% 0% 1% 0%
[libx264 @ 0x59fd61ed4700] i8c dc,h,v,p: 9% 11% 73% 7%
[libx264 @ 0x59fd61ed4700] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x59fd61ed4700] ref P L0: 60.2% 9.9% 19.9% 10.0%
[libx264 @ 0x59fd61ed4700] ref B L0: 74.3% 24.5% 1.2%
[libx264 @ 0x59fd61ed4700] ref B L1: 97.9% 2.1%
[libx264 @ 0x59fd61ed4700] kb/s:1500.79
4. Divisão das matrizes em slots e batches¶
- Cada exemplo contem 50 pacotes. (Parâmetro window_size)
- São definidos alguns subconjuntos:
- Proximity: Train_m1, Test_m1, Train_m2, Test_m2, Train_m3, Test_m3.
- Coarse: Train, Test.
- Fine grained: Train_m1, Test_m1, Train_m2, Test_m2, Train_m3, Test_m3.
SaÃda
- Cada batch é uma 50 × 242. 50 pacotes por 242 subportadoras.
- Não percebi agregação e nem normalização.
Seleção do dado para cada Slot
- Os Ãndices não começam em zero e existe um pequeno intervalo ("gap") de amostras entre conjuntos de treino e teste para evitar sobreposição.
- Além disso, 5 janelas (equivalentes a 5 × 50 amostras) são descartadas no inÃcio e no final de cada slot, reduzindo ruÃdos de borda.
# Essas variáveis estão no código Matlab e definem os intervalos de cada Slot
# A quantidade total de amostras nos arquivos de entrada é fixada em 814 (um "número mágico" pré-definido).
# Os Ãndices dos slots são determinados com base em divisões proporcionais desse valor, criando separações entre treino e teste.
proximity_data = {
'Task': ["Train_m1", "Test_m1", "Train_m2", "Test_m2", "Train_m3", "Test_m3"],
'Start': [5, 180, 245, 427, 490, 672],
'End': [180, 240, 425, 485, 670, 730]
}
coarse_data = {
'Task': ["Train", "Test"],
'Start': [5, 242],
'End': [240, 300]
}
fine_grained = {
'Task': ["Train_m1", "Test_m1", "Train_m2", "Test_m2", "Train_m3", "Test_m3"],
'Start': [5, 180, 245, 427, 490, 672],
'End': [180, 240, 425, 485, 670, 730]
}
def plot_slots(data, title):
df = pd.DataFrame(data)
df['Duration'] = (df['End'] - df['Start'])
fig, ax = plt.subplots(1, figsize=(10, 5))
for i in range(len(df)):
ax.barh(y=i, width=df['Duration'][i], left=df['Start'][i], height=0.5)
ax.set_yticks(range(len(df)))
ax.set_yticklabels(df['Task'])
ax.set_xlabel('Sample ratio index')
ax.set_xlim(0, 814)
ax.invert_yaxis()
ax.grid(axis='x', linestyle='--')
plt.title(title)
plot_slots(coarse_data, "Coarse")
plot_slots(proximity_data, "Proximity")
plot_slots(fine_grained, "Fine Grained")
def summarize_batches(output='SAIDAS/03-batch_summary.csv'):
if os.path.exists(output):
return pd.read_csv(output)
else:
df_proto = {
'test': [],
'environment': [],
'monitor': [],
'slot': [],
'activity': [],
'shape0': [],
'shape1': [],
'file_path': []
}
def getShape(mat_file_path):
data = scipy.io.loadmat(mat_file_path)
return data['csi_mon'].shape
file_paths = Path('../Data').rglob('*.mat')
for file_path in tqdm(sorted(file_paths)):
file_path = str(file_path)
if 'Slots' in file_path:
file_path_splited = file_path.split('/')
test = file_path_splited[2]
environment = file_path_splited[3]
monitor = file_path_splited[6]
slot = file_path_splited[8]
activity = file_path_splited[9].split('_')[0]
shape0, shape1 = getShape(file_path)
file_path = file_path_splited[10]
df_proto['test'].append(test)
df_proto['environment'].append(environment)
df_proto['monitor'].append(monitor)
df_proto['slot'].append(slot)
df_proto['activity'].append(activity)
df_proto['shape0'].append(shape0)
df_proto['shape1'].append(shape1)
df_proto['file_path'].append(file_path)
df = pd.DataFrame(data)
df['Duration'] = (df['End'] - df['Start'])
return df[['Task', 'Start', 'End', 'Duration']].to_csv(output, index=False)
batches_summary = summarize_batches()
print(f'Total de batches: {len(batches_summary)}')
batches_summary.head()
Total de batches: 2496403
| test | environment | monitor | slot | activity | shape0 | shape1 | file_path | |
|---|---|---|---|---|---|---|---|---|
| 0 | coarse | Classroom | m1 | Test | A | 50 | 242 | batch_0.mat |
| 1 | coarse | Classroom | m1 | Test | A | 50 | 242 | batch_1.mat |
| 2 | coarse | Classroom | m1 | Test | A | 50 | 242 | batch_10.mat |
| 3 | coarse | Classroom | m1 | Test | A | 50 | 242 | batch_100.mat |
| 4 | coarse | Classroom | m1 | Test | A | 50 | 242 | batch_101.mat |
n_pacotes_original = mat_summary['shape1'].sum()
n_pacotes_apos_batches = batches_summary['shape0'].sum()
print(f"Pacotes originais: {n_pacotes_original}")
print(f"Pacotes após batches: {n_pacotes_apos_batches}")
print(f'Diferença: {n_pacotes_original - n_pacotes_apos_batches} pacotes')
print(f'O número de pacotes do batches correspondem a {n_pacotes_apos_batches / n_pacotes_original * 100:.2f}% do número de pacotes originais')
Pacotes originais: 218927963 Pacotes após batches: 124820150 Diferença: 94107813 pacotes O número de pacotes do batches correspondem a 57.01% do número de pacotes originais
def plot_resumo_processamento_batches():
percentual = n_pacotes_apos_batches / n_pacotes_original * 100
labels = ['Pacotes Originais', 'Pacotes Após Batches']
values = [n_pacotes_original, n_pacotes_apos_batches]
colors = ['#4CAF50', '#2196F3']
# Plot
fig, ax = plt.subplots(figsize=(8, 5))
bars = ax.barh(labels, values, color=colors)
# Adiciona os valores nos gráficos
for i, bar in enumerate(bars):
width = bar.get_width()
if i == 1: # para "Pacotes Após Batches"
texto = f'{width:,}\n({percentual:.2f}%)'
else:
texto = f'{width:,}'
ax.text(width + 5e6, bar.get_y() + bar.get_height() / 2, texto, va='center', fontsize=10)
# TÃtulo e eixos
ax.set_xlabel('Número de Pacotes')
ax.set_title('Resumo do Processamento de Pacotes')
plt.xlim(0, 240_000_000)
plt.tight_layout()
plot_resumo_processamento_batches()
5. Criando os CSVs¶
A geração de CSV é realizada utilizando script em python que estão no diretório SiMWiSense/Python_code/
Este script é bastante rápido, com execução praticamente instantânea.
Principais observações:
- Os arquivos CSV gerados contêm duas colunas: filename e label.
- A geração dos arquivos respeita a divisão em batches e slots feita no passo anterior.
- Não parece haver qualquer tipo de normalização nos valores gerados.
def summarize_csvs(output='SAIDAS/04-csv_summary.csv'):
if os.path.exists(output):
return pd.read_csv(output)
else:
def add_shape(row_csv_df, base_folder):
mat_file_path = row_csv_df['filename']
data = scipy.io.loadmat(f'{base_folder}/{mat_file_path}')
row_csv_df['nr_packets'], row_csv_df['nr_subcarriers'] = data['csi_mon'].shape
return row_csv_df
df_all = pd.DataFrame({
'test': [],
'environment': [],
'monitor': [],
'slot': [],
'csv_file_path': [],
'filename': [],
'label': [],
'nr_packets': [],
'nr_subcarriers': []
})
file_paths = Path('../Data').rglob('*.csv')
for file_path in tqdm(sorted(file_paths)):
# print(f'Processing {file_path}')
file_path = str(file_path)
df = pd.read_csv(file_path)
base_folder = os.path.dirname(file_path)
df = df.apply(add_shape, axis=1, base_folder=base_folder)
file_path_splited = file_path.split('/')
test = file_path_splited[2]
environment = file_path_splited[3]
monitor = file_path_splited[6]
slot = file_path_splited[8]
df['test'] = test
df['environment'] = environment
df['monitor'] = monitor
df['slot'] = slot
df['csv_file_path'] = file_path
df = df[['test', 'environment', 'monitor', 'slot', 'csv_file_path', 'filename', 'label', 'nr_packets', 'nr_subcarriers']]
df_all = pd.concat([df_all, df], ignore_index=True)
# para anotar se faz parte do conjunto de validação
df_all['set'] = df_all['csv_file_path'].apply(lambda x: 'val' if 'val' in x else ('test' if 'test' in x else 'train'))
df_all.to_csv(output, index=False)
return df_all
csv_summary = summarize_csvs()
csv_summary.head()
| test | environment | monitor | slot | csv_file_path | filename | label | nr_packets | nr_subcarriers | set | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | coarse | Classroom | m1 | Test | ../Data/coarse/Classroom/80MHz/3mo/m1/Slots/Te... | C_batch/batch_278.mat | C | 50.0 | 242.0 | test |
| 1 | coarse | Classroom | m1 | Test | ../Data/coarse/Classroom/80MHz/3mo/m1/Slots/Te... | C_batch/batch_533.mat | C | 50.0 | 242.0 | test |
| 2 | coarse | Classroom | m1 | Test | ../Data/coarse/Classroom/80MHz/3mo/m1/Slots/Te... | C_batch/batch_350.mat | C | 50.0 | 242.0 | test |
| 3 | coarse | Classroom | m1 | Test | ../Data/coarse/Classroom/80MHz/3mo/m1/Slots/Te... | C_batch/batch_57.mat | C | 50.0 | 242.0 | test |
| 4 | coarse | Classroom | m1 | Test | ../Data/coarse/Classroom/80MHz/3mo/m1/Slots/Te... | C_batch/batch_532.mat | C | 50.0 | 242.0 | test |
n_pacotes_csvs = csv_summary['nr_packets'].sum()
print(f"Pacotes originais: {n_pacotes_original}")
print(f"Pacotes após batches: {n_pacotes_apos_batches}")
print(f"Pacotes após csvs: {n_pacotes_csvs}")
print(f'Diferença: {n_pacotes_apos_batches - n_pacotes_csvs} pacotes com o passo anterio')
Pacotes originais: 218927963 Pacotes após batches: 124820150 Pacotes após csvs: 124820150.0 Diferença: 0.0 pacotes com o passo anterio
def plot_dist(df, column_to_count, title, sort_ascending=False):
total = len(df)
if sort_ascending:
order = df[column_to_count].sort_values().unique()
else:
order = df[column_to_count].value_counts().index
ax = sns.countplot(x=column_to_count, data=df, order=order)
# Adiciona os percentuais acima de cada barra
for p in ax.patches:
count = p.get_height()
percentage = f'{100 * count / total:.1f}%'
ax.text(p.get_x() + p.get_width() / 2., count + 0.5, percentage,
ha='center', va='bottom', fontsize=10)
plt.title(title)
plt.xlabel(column_to_count)
plt.ylabel('Count')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
tests = ['coarse', 'proximity', 'fine_grained']
environments = ['Classroom', 'Office']
for test in tests:
for environment in environments:
subset = csv_summary.loc[(csv_summary['test'] == test) & (csv_summary['environment'] == environment)]
title = f'{test} {environment} SET Distribution'
plot_dist(subset, 'set', title)
tests = ['coarse', 'proximity', 'fine_grained']
environments = ['Classroom', 'Office']
for test in tests:
for environment in environments:
subset = csv_summary.loc[(csv_summary['test'] == test) & (csv_summary['environment'] == environment)]
sets = subset['set'].unique()
for sset in sets:
subset_set = subset[subset['set'] == sset]
title = f'{test} {environment} {sset} Distribution'
plot_dist(subset_set, 'label', title, sort_ascending=True)
Bias no dataset¶
- As ativadades não estão balanceadas no classroom.
- PossÃvel problema: Quando ele justifica a melhor performance do modelo treinado no Classroom e avaliado no Office, esse desbalanceamento pode fazer o modelo treinado no Classroom performar pior no Office de maneira artificial e não clara no texto. Figure 15 Performance of FREL in simultaneous activity sensing with new untrained environments
6. Exemplos de amostras¶
# Exemplo dos csvs gerados
csv_path = '../Data/proximity/Classroom/80MHz/3mo/m1/Slots/Train_m1/train_set.csv'
df = pd.read_csv(csv_path)
df.sample(n=10)
| filename | label | |
|---|---|---|
| 23695 | B_batch/batch_2152.mat | B |
| 33095 | H_batch/batch_1054.mat | H |
| 18136 | T_batch/batch_511.mat | T |
| 33726 | H_batch/batch_1517.mat | H |
| 30698 | S_batch/batch_1184.mat | S |
| 6981 | R_batch/batch_933.mat | R |
| 802 | O_batch/batch_1825.mat | O |
| 8053 | R_batch/batch_1660.mat | R |
| 29128 | A_batch/batch_4261.mat | A |
| 42076 | D_batch/batch_2459.mat | D |
labels = sorted(csv_summary['label'].unique().tolist())
num_rows = len(labels)
num_cols = 5
largura_pixels = num_cols * 275
altura_pixels = num_rows * 80
dpi = 100
figsize = (largura_pixels / dpi, altura_pixels / dpi)
fig, axes = plt.subplots(num_rows, num_cols, figsize=figsize, sharex=True, sharey=True, squeeze=False)
row_index, col_index = 0, 0
for row_index in range(num_rows):
sample_indexes = csv_summary[csv_summary['label'] == labels[row_index]].sample(num_cols).index
for col_index in range(num_cols):
sample_index = sample_indexes[col_index]
csv_path = csv_summary.loc[sample_index]['csv_file_path']
sample_file_path = csv_summary.loc[sample_index]['filename']
base_folder = os.path.dirname(csv_path)
sample_file_path = os.path.join(base_folder, sample_file_path)
data = scipy.io.loadmat(sample_file_path)['csi_mon']
real_part = np.real(data)
imag_part = np.imag(data)
real_part_norm = (real_part - real_part.min()) / (real_part.max() - real_part.min())
imag_part_norm = (imag_part - imag_part.min()) / (imag_part.max() - imag_part.min())
h, w = real_part.shape # altura e largura
rgb_image = np.zeros((h, w, 3))
rgb_image[..., 0] = real_part_norm # Red
rgb_image[..., 1] = imag_part_norm # Green
rgb_image[..., 2] = (real_part_norm * imag_part_norm)**0.00001
axes[row_index][col_index].imshow(rgb_image, cmap='viridis')
# axes[row_index][col_index].axis('off')
if col_index == 0:
axes[row_index][col_index].set_ylabel(labels[row_index], rotation=0, labelpad=50, va='center', ha='right', fontsize=12)
# plt.subplots_adjust(left=0, right=1, top=1, bottom=0)
plt.tight_layout()
plt.suptitle(f'Amostras de matrizes (50,242)')
t-SNE¶
def plot_tsne_activities_by_test_environment_monitor_slot(csv_summary, test, environment, monitor, slot, set_set, subsample=None, seed=42, perplexity=30):
output_file = f'SAIDAS/05-tsne_activities_by_{test}_{environment}_{monitor}_{slot}_{set_set}.png'
if os.path.exists(output_file):
img = plt.imread(output_file)
plt.imshow(img)
plt.axis('off')
plt.show()
return
subset = csv_summary.loc[
(csv_summary['test'] == test)
&(csv_summary['environment'] == environment)
&(csv_summary['set'] == set_set)
&(csv_summary['monitor'] == monitor)
&(csv_summary['slot'] == slot)
]
if subsample is not None:
subset = subset.sample(n=subsample, random_state=seed)
X = np.zeros((len(subset), 50 * 242 *2))
for i in range(len(subset)):
csv_path = subset.iloc[i]['csv_file_path']
sample_file_path = subset.iloc[i]['filename']
base_folder = os.path.dirname(csv_path)
sample_file_path = os.path.join(base_folder, sample_file_path)
data = scipy.io.loadmat(sample_file_path)['csi_mon']
real_part = np.real(data)
imag_part = np.imag(data)
X[i] = np.concatenate((real_part.flatten(), imag_part.flatten()))
X = X.astype(np.float32)
labels = subset['label'].tolist()
label_encoder = LabelEncoder()
numeric_labels = label_encoder.fit_transform(labels)
class_names = label_encoder.classes_
colormap = 'tab20' if len(labels) > 10 else 'tab10'
tsne = TSNE(n_components=2, perplexity=perplexity, random_state=42)
X_embedded = tsne.fit_transform(X)
plt.figure(figsize=(8,6))
plt.scatter(X_embedded[:, 0], X_embedded[:, 1], c=numeric_labels, cmap=colormap, s=5)
plt.title(f't-SNE test: {test}, environment: {environment}, monitor: {monitor}, slot: {slot}, set: {set_set}')
plt.xlabel('t-SNE Component 1')
plt.ylabel('t-SNE Component 2')
plt.grid(True)
plt.tight_layout()
plt.legend(handles=[plt.Line2D([0], [0], marker='o', color='w', label=class_name, markersize=5, markerfacecolor=plt.cm.tab10(i)) for i, class_name in enumerate(class_names)], loc='upper right', bbox_to_anchor=(1.15, 1))
plt.savefig(output_file, dpi=300, bbox_inches='tight')
plt.show()
def plot_tsne_monitor_by_label_test_environment_slot(csv_summary, test, environment, slot, set_set, subsample=None, seed=42, perplexity=30, label='A'):
output_file = f'SAIDAS/05-tsne_monitor_by_{label}_{test}_{environment}_{slot}_{set_set}.png'
if os.path.exists(output_file):
img = plt.imread(output_file)
plt.imshow(img)
plt.axis('off')
plt.show()
return
subset = csv_summary.loc[
(csv_summary['test'] == test)
&(csv_summary['label'] == label)
&(csv_summary['environment'] == environment)
&(csv_summary['set'] == set_set)
&(csv_summary['slot'] == slot)
]
if subsample is not None:
subset = subset.sample(n=subsample, random_state=seed)
X = np.zeros((len(subset), 50 * 242 *2))
for i in range(len(subset)):
csv_path = subset.iloc[i]['csv_file_path']
sample_file_path = subset.iloc[i]['filename']
base_folder = os.path.dirname(csv_path)
sample_file_path = os.path.join(base_folder, sample_file_path)
data = scipy.io.loadmat(sample_file_path)['csi_mon']
real_part = np.real(data)
imag_part = np.imag(data)
X[i] = np.concatenate((real_part.flatten(), imag_part.flatten()))
X = X.astype(np.float32)
labels = subset['monitor'].tolist()
label_encoder = LabelEncoder()
numeric_labels = label_encoder.fit_transform(labels)
class_names = label_encoder.classes_
colormap = 'tab20' if len(labels) > 10 else 'tab10'
tsne = TSNE(n_components=2, perplexity=perplexity, random_state=42)
X_embedded = tsne.fit_transform(X)
plt.figure(figsize=(8,6))
plt.scatter(X_embedded[:, 0], X_embedded[:, 1], c=numeric_labels, cmap=colormap, s=5)
plt.title(f't-SNE label: {label} test: {test}, environment: {environment}, slot: {slot}, set: {set_set}')
plt.xlabel('t-SNE Component 1')
plt.ylabel('t-SNE Component 2')
plt.grid(True)
plt.tight_layout()
plt.legend(handles=[plt.Line2D([0], [0], marker='o', color='w', label=class_name, markersize=5, markerfacecolor=plt.cm.tab10(i)) for i, class_name in enumerate(class_names)], loc='upper right', bbox_to_anchor=(1.15, 1))
plt.savefig(output_file, dpi=300, bbox_inches='tight')
plt.show()
csv_summary_activities_subsets = csv_summary.loc[csv_summary['set'] == 'test'][['test', 'environment', 'monitor', 'slot']].drop_duplicates()
for _, row in csv_summary_activities_subsets.iterrows():
test = row['test']
environment = row['environment']
monitor = row['monitor']
slot = row['slot']
set_set = 'test'
plot_tsne_activities_by_test_environment_monitor_slot(csv_summary, test, environment, monitor, slot, set_set, perplexity=100)
csv_summary_activityA_subsets = csv_summary.loc[(csv_summary['set'] == 'test') & (csv_summary['label'] == 'A')][['test', 'environment', 'slot']].drop_duplicates()
for _, row in csv_summary_activityA_subsets.iterrows():
label = 'A'
test = row['test']
environment = row['environment']
slot = row['slot']
set_set = 'test'
plot_tsne_monitor_by_label_test_environment_slot(csv_summary, test, environment, slot, set_set, perplexity=100)